﻿// The MIT License (MIT)
//
// Copyright (c) 2015 FramTack, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), 
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//
// For more information visit the project home page at http://solutionfamily.codeplex.com or the owner's site at http://solution-family.com
//

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;
using System.Net;
using System.Diagnostics;
using OpenNETCF;

namespace SolutionFamily.IO.Simma
{
    public class Simma1708 : IJ1708Bus
    {
        public event EventHandler<GenericEventArgs<J1708ReceiveMessage>> MessageReceived;

        private VNA232 m_vna;

        public Simma1708(VNA232 parent)
        {
            m_vna = parent;
        }

        internal void RaiseMessageReceived(J1708ReceiveMessage message)
        {
            MessageReceived.Fire(this, new GenericEventArgs<J1708ReceiveMessage>(message));
        }

        public void Send(J1708TransmitMessage message)
        {
            var length = message.Payload.Length + 6; // data + message ID (1) + mid (1) + pid (2) + priority (1) + chksum (1)

            var buffer = new byte[length + 3]; // length + sentinel (1)  + length data (2)

            buffer[0] = 192;                    // simma sentinel
            buffer[1] = (byte)(length >> 8);    // length MSB
            buffer[2] = (byte)(length & 0xFF);  // length LSB

            buffer[3] = (byte)MessageIdentifier.Tx1587;
            buffer[4] = message.MID;
            buffer[5] = (byte)(message.PID >> 8); // TODO: is the endianness right here?
            buffer[6] = (byte)(message.PID & 0xFF);
            buffer[7] = message.Priority;
            Buffer.BlockCopy(message.Payload, 0, buffer, 8, message.Payload.Length);

            // checksum
            var e = VNA232.TwosComplement(0, buffer, 1, buffer.Length - 2);
            buffer[buffer.Length - 1] = (byte)(256 - e);

            m_vna.Send(buffer);
        }

        public void Subscribe(ushort pid)
        {
            Debug.WriteLine("Subscribe to PID: " + pid.ToString());

            var accept = new J1587AcceptanceFilterAdd(pid);
            m_vna.Send(accept.Serialize());
        }

        public void Unsubscribe(ushort pid)
        {
            throw new NotImplementedException();
        }
    }
}
